#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#ifndef _IOT_TO_ALIYUN_H_
#define _IOT_TO_ALIYUN_H_
/***********************************************************************
  *Copyright 2020-03-06, pyfree
  *
  *File Name       : iot_to_aliyun.h
  *File Mark       :
  *Summary         : 阿里云物联网的接口实现
  *
  *
  *Current Version : 1.00
  *Author          : PengYong
  *FinishDate      :
  *
  *Replace Version :
  *Author          :
  *FinishDate      :

 ************************************************************************/
#include <string>
#include <vector>
#include <queue>
#include <map>

#include "lib_acl.h"
#include "acl_cpp/lib_acl.hpp"
//
#include "datadef.h"
#include "conf_app.h"
#include "queuedata.h"
#include "queuedata_single.h"

class ProducerAliyun;
class ConsumerAliyun;

//阿里云物联网上送事件描述
struct ALiyunEventOut : public pyfree::ALiyunEventInfo
{
	void toVec();
	std::vector<std::string> outs;
};

class IOToAliyun : public acl::thread
{
public:
	IOToAliyun(void);
	virtual ~IOToAliyun(void);

	void* run();
private:
	/**
	 * 接口初始化,完成配置信息的读取、转换,完成消费者、生成者等接口实例化,完成阿里云sdk库调用的初始化工作
	 * @return {void}
	 */
	void init();
	/**
	 * 释放阿里云sdk库调用所需配置、资源,释放其他相关接口实例
	 * @return {void}
	 */
	void uninit();
	/**
	 * 完成阿里云物联网平台接口初始化和参数设置工作,构建接口实例
	 * @return {void}
	 */
	void create();
	/**
	 * 阿里云物联网平台接口实例释放
	 * @return {void}
	 */
	void destroy();
	/**
	 * 进行主题订购设置
	 * @param gatewayFlag {bool } 是否为网关设备的主题订购还是子设备的主题订购配置
	 * @return {void}
	 */
	void subscribe(bool gatewayFlag);
	/**
	 * 取消主题订购设置
	 * @return {void}
	 */
	void unsubscribe();
	/**
	 * 设备注册
	 * @return {void}
	 */
	void devOnLine();
	/**
	 * 取消设备注册
	 * @return {void}
	 */
	void devOffLine();
	/**
	 * 设备标签信息添加
	 * @return {void}
	 */
	void devTagUp();
	/**
	 * 设备标签信息删除
	 * @return {void}
	 */
	void devTagDel();
	/**
	 * 从缓存队列中获取需要上送信息点态势集合
	 * @param its {map<ulong,queue>& } 信息点态势集合
	 * @param sizel {int} 指定一次最大获取信息点的个数
	 * @return {bool} 获取结果是否不为空
	 */
	bool getCacheInfos(std::map<unsigned long long, std::queue<JsonPValue> > &its,int sizel=10);
	/**
	 * 发布信息点属性(态势)
	 * @return {void}
	 */
	void sendProperty();
	/**
	 * 发布事件信息
	 * @return {void}
	 */
	void sendEvent();
	/**
	 * 根据设备编号获取发布属性的主题
	 * @param devId {ulong} 设备编号
	 * @return {void}
	 */
	std::string getAliyunPostTopic(unsigned long long devId);
	/**
	 * 获取事件发布主题
	 * @return {void}
	 */
	std::string getAliyunEventUpTopic();
	/**
	 * 根据设备编号获取更新标签的主题
	 * @param devId {ulong} 设备编号
	 * @return {void}
	 */
	std::string getAliyunTagUpTopic(unsigned long long devId);
	/**
	 * 根据设备编号获取删除标签的主题
	 * @param devId {ulong} 设备编号
	 * @return {void}
	 */
	std::string getAliyunTagDelTopic(unsigned long long devId);
	/**
	 * 根据设备编号和信息点编号获取信息点态势(属性)发布的主题
	 * @param devId {ulong} 设备编号
	 * @param pId {uint} 信息点编号
	 * @return {void}
	 */
	std::string getAliyunKey(unsigned long long devId, unsigned int pId);
private:
	bool running;					//线程运行标记
	bool initLink;					//连接初始标记,接口每次重新连接时,需要进行主题订购、设备注册、标签推送等业务处理
	pyfree::AliyunTriples gatewayTriples;	//主要存储阿里云通信的网关设备三元组信息
	ALiyunEventOut gatewayEI;				//上送事件描述信息
	std::map<unsigned long long, pyfree::AliyunDevices> deviceTriples;	//各个子设备的三元组信息
	std::map<std::string, AliyunDeviceMaps> subTopicMaps;				//存储订购主题信息
	void *pclient;		//连接阿里云物联网平台的通信接口句柄
	char *msg_buf;		//阿里云物联网平台的通信接口写入缓存
	char *msg_readbuf;	//阿里云物联网平台的通信接口读取缓存
	QueueDataSingle<JsonEvent> *to_aliyun_event_queue;				//上送阿里云的事件缓存,由告警模块添加入队列
	QueueDataSingle<SocketAliyunWriteItem> *cache_to_aliyun_queue;	//上送阿里云的态势(属性)缓存,由采集模块添加入队列
	unsigned long long cnt;					//发布消息需要的标号
	ProducerAliyun *producer;				//生成者接口
	ConsumerAliyun *consumer;				//消费者接口
};

#endif
